package com.wingtech.sheyifan;

import com.jfoenix.controls.*;
import com.wingtech.sheyifan.device.ADBDeviceManager;
import com.wingtech.sheyifan.device.DeviceManager;
import com.wingtech.sheyifan.device.LogOptions;
import com.wingtech.sheyifan.front.Interactor;
import com.wingtech.sheyifan.front.Layer;
import com.wingtech.sheyifan.front.Profile;
import com.wingtech.sheyifan.shared.Logger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.image.Image;
import javafx.scene.layout.StackPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;

public class Main extends Application {
    public static JFXTextField logPath;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws IOException {
        var fxmlURL = Main.class.getResource("fxml/main.fxml");
        if (fxmlURL == null) {
            Logger.printToolError("Error: cannot find FXML file.");
            // 2020-12-11 11:28 sheyifan Issue: quit javafx application
            Platform.exit();
        }
        assert fxmlURL != null;
        StackPane root = FXMLLoader.load(fxmlURL);

        primaryStage.getIcons().addAll(new Image(Main.class.getResourceAsStream("res/images/FXLogcat.png")));
        primaryStage.setTitle("FXLogcat");

        var scene = new Scene(root, 700, 500);

        Main.logPath = (JFXTextField) root.lookup("#log-location");

        var connectDevice = (JFXButton) root.lookup("#connect");
        // 2021-03-21 sheyifan Issue: flag to enable log cat or not
        var connectStatus = (JFXCheckBox) root.lookup("#connect-status");
        flushConnectStatus(connectStatus);

        // 2020-12-12 22:10 sheyifan Issue: set profiles in the front
        var profile = new Profile(root);
        profile.setAll();
        // 2020-12-12 21:02 sheyifan Issue: manage all events in the front
        var interactor = new Interactor(root);
        interactor.connectAll();
        // 2020-12-12 21:02 sheyifan Issue: manage layout in the front
        var layer = new Layer(root);
        layer.manageAll();

        connectDevice.setOnAction(actionEvent -> flushConnectStatus(connectStatus));

        // 2021-03-20 sheyifan Issue: bind enable property to device status
        root.lookup("#icon-dir").disableProperty().bind(connectStatus.selectedProperty().not());
        var exportLogButton = (JFXButton) root.lookup("#export-log-button");
        if (exportLogButton != null) {

        }
        else {
            Logger.printToolLog("Error: cannot find export log button.");
        }
        for (var logOption: root.lookupAll(".log-item")) {
            logOption.disableProperty().bind(connectStatus.selectedProperty().not());
        }

        if (Main.logPath != null) {
            // Main.logPath.disableProperty().bind(connectStatus.selectedProperty().not());
        }
        else {
            Logger.printToolLog("Error: cannot find log path textfield.");
        }

        var fileIcon = (Label) root.lookup("#icon-dir");
        fileIcon.disableProperty().unbind();
        File[] logPathStr = new File[1];
        fileIcon.setOnMousePressed(event -> {
            fileIcon.setStyle("-fx-font-size: 18");

            var directoryChooser = new DirectoryChooser();
            directoryChooser.setTitle("Select Log path");
            logPathStr[0] = directoryChooser.showDialog(primaryStage);

            if (logPathStr[0] != null && Main.logPath != null) {
                Main.logPath.setText(logPathStr[0].getAbsolutePath());
            }
        });
        fileIcon.setOnMouseReleased(event -> fileIcon.setStyle("-fx-font-size: 20"));

        if (exportLogButton != null) {
            exportLogButton.setOnAction(event -> {
                if (!flushConnectStatus(connectStatus)) {
                    return;
                }

                exportLogButton.setDisable(true);
                logPath.setDisable(true);
                fileIcon.setDisable(true);

                var waitIndicator = (ProgressIndicator) root.lookup("#export-progress");
                waitIndicator.setOpacity(1);
                DeviceManager deviceManager = new ADBDeviceManager();

                new Thread(() -> {
                    deviceManager.exportLog(new LogOptions(
                            ((JFXCheckBox) root.lookup("#ifconfig")).isSelected(),
                            ((JFXCheckBox) root.lookup("#iptable")).isSelected(),
                            ((JFXCheckBox) root.lookup("#iproute")).isSelected(),
                            ((JFXCheckBox) root.lookup("#dns")).isSelected(),
                            ((JFXCheckBox) root.lookup("#sim")).isSelected(),
                            ((JFXCheckBox) root.lookup("#qcmap")).isSelected(),
                            ((JFXCheckBox) root.lookup("#ping")).isSelected(),
                            ((JFXCheckBox) root.lookup("#system-log")).isSelected(),
                            ((JFXCheckBox) root.lookup("#boot")).isSelected(),
                            ((JFXCheckBox) root.lookup("#version")).isSelected(),
                            ((JFXCheckBox) root.lookup("#adb-log")).isSelected(),
                            ((JFXCheckBox) root.lookup("#tcpdump")).isSelected(),
                            ((JFXCheckBox) root.lookup("#tmp")).isSelected(),
                            Paths.get(Main.logPath.getText())
                    ));

                    waitIndicator.setOpacity(0);
                    exportLogButton.setDisable(false);
                    logPath.setDisable(false);
                    fileIcon.setDisable(false);

                    Logger.printToolLog("Finish!");
                }).start();
            });
        }

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param connectStatus checkbox to indicate connection status
     * @return connected or not
     */
    public static boolean flushConnectStatus(JFXCheckBox connectStatus) {
        // 2021-03-21 sheyifan Issue: test connection of device when initializing
        DeviceManager deviceManager = new ADBDeviceManager();
        try {
            var connected = deviceManager.testConnection();
            if(connected) {
                connectStatus.setSelected(true);
                return true;
            }
            else {
                connectStatus.setSelected(false);
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }

        return false;
    }
}
